using System.Windows.Forms;
using NUnit.Framework;
using Rhino.Mocks;
using ShadeTree.Binding.Elements;
using ShadeTree.Binding.Settings;

namespace ShadeTree.Binding.Tests.Elements
{
    [TestFixture]
    public class PicklistElementTester
    {
        #region Setup/Teardown

        [SetUp]
        public void SetUp()
        {
            LastChosenValues.Clear();
        }

        #endregion

        [Test]
        public void BindThenResetThenApplyChanges()
        {
            var box = new ComboBox();
            box.Items.AddRange(new[] {"TX", "CT", "MO"});

            Accessor property = SingleProperty.Build<PicklistTarget>(x => x.State);
            var target = new PicklistTarget();

            var element = new PicklistElement(property, box);
            target.State = "CT";

            element.Bind(target);
            Assert.AreEqual(target.State, box.SelectedItem);

            box.SelectedItem = "TX";
            element.Reset();
            Assert.AreEqual(target.State, box.SelectedItem);

            box.SelectedItem = "TX";
            element.ApplyChanges();
            Assert.AreEqual("TX", target.State);
        }


        [Test]
        public void GetACallback()
        {
            Accessor property = SingleProperty.Build<PicklistTarget>(x => x.State);
            var target = new PicklistTarget();
            var box = new ComboBox();
            box.Items.AddRange(new[] {"a", "b", "c"});
            var element = new PicklistElement(property, box);
            element.Bind(target);

            bool wasCalled = false;
            element.RegisterChangeHandler(delegate { wasCalled = true; });
            box.SelectedItem = "b";

            Assert.IsTrue(wasCalled);
        }

        [Test]
        public void LostFocusTellsTheParentScreenBinderToValidate()
        {
            var box = new ComboBox();
            box.Items.AddRange(new[] {"TX", "CT", "MO"});

            Accessor property = SingleProperty.Build<PicklistTarget>(x => x.State);
            var target = new PicklistTarget();

            var element = new PicklistElement(property, box);

            var binder = MockRepository.GenerateMock<IScreenBinder>();
            binder.Expect(x => x.IsLatched).Return(false);
            element.Binder = binder;

            binder.Expect(x => x.Validate(element));

            TestUtility.FireEvent(box, "LostFocus");
        }

        [Test]
        public void SetDefaultsWhenThereIsOnlyOneChoiceInTheList()
        {
            Accessor property = SingleProperty.Build<PicklistTarget>(x => x.State);
            var target = new PicklistTarget();
            var box = new ComboBox();
            box.Items.AddRange(new[] {"c"});
            var element = new PicklistElement(property, box);
            element.Bind(target);

            target.State.ShouldBeNull();
            element.SetDefaults();
            target.State.ShouldEqual("c");
        }


        [Test]
        public void SetDefaultsWhenThereIsTwoChoiceInTheListDoesNothing()
        {
            Accessor property = SingleProperty.Build<PicklistTarget>(x => x.State);
            var target = new PicklistTarget();
            var box = new ComboBox();
            box.Items.AddRange(new[] {"b", "c"});
            var element = new PicklistElement(property, box);
            element.Bind(target);

            target.State.ShouldBeNull();
            element.SetDefaults();
            target.State.ShouldBeNull();
        }

        [Test]
        public void SettingADefaultFiresChangeEvents()
        {
            Accessor property = SingleProperty.Build<PicklistTarget>(x => x.State);
            var target = new PicklistTarget();
            var box = new ComboBox();
            box.Items.AddRange(new[] {"c"});
            var element = new PicklistElement(property, box);
            element.Bind(target);


            bool iWasCalled = false;
            element.RegisterChangeHandler(( ) => iWasCalled = true);
            element.SetDefaults();
            iWasCalled.ShouldBeTrue();
        }
    }

    internal class PicklistTarget
    {
        public string State { get; set; }


        public string[] Colors { get; set; }
    }
}